/*-+-*****************************************************************************
 Copyright (C) 2009-2012 Oceanside Software Corporation (R)
 Dallas, Texas

 Author       : Jason T. Brower
 Purpose      : This file is part of a point-of-sale software package
                originally written for Table-Service Restaurants.
              
 Date         : July 8th of 2012
              
 History      : The application that this software file belongs to was 
                written over a 3-Year period.  The first version was written
                in C# .Net 3.5 using Windows Forms.  Being new to .Net at
                the time, I soon learned of Windows Presentation Foundation,
                liked the graphics capabilities and databinding so I
                migrated to WPF.  When the .Net 4.0 framework was released
                the application was migrated from 3.5 to 4.0. Now today,
                .Net 4.5 RC is out and I was already in process of migrating
                before I made this public.
                
Excuse Me     : Please excuse the coding style, it is not representative of
                my typical work.  During the three years I was under a very
                tight budget, constantly running out of funding and was 
                working 18 hour days hyped up on 5-Hour Energy.  The 
                design is not textbook.  It is monolythic because of
                previous issues I will not get into.  There are few comments
                in the code and the ones that are there may be incorrect.
                
What it is not: This is not the exact version that I took through PA-DSS 2.0
                nor is it the exact version running at my customer sites.
                I removed some details for security purposes including some
                encryption algorithms.  The reporting was removed because
                I was including a third party library that cannot be 
                published with this Open Source.
                
What it is    : This application has been running at high volume restaraunts
                for over a year.  It never freezes, crashes or does anything
                unexpected.  So long as it is built, installed and configured
                correctly, it is a strong system that we can all enhance.

Contact       : Please note that I can no longer work for free.  However, you
                can reach me at information@oceansidesw.com.                                                      

*********************************************************************************/
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Collections;
#if _LOCALDB
  using Oceanside.LocalDB;
#else
using Oceanside.RemoteDB;
#endif
namespace Oceanside
{
    /// <summary>
    /// 
    /// </summary>
    public partial class PageDataToolsImp : PageImpBaseClass
    {
        Button_164_62 bExportAuditLog;

        /// <summary>
        /// Constructor
        /// </summary>
        public PageDataToolsImp(Button_164_62 bExportAuditLog, Button_164_62 bInjectProducts)
        {
            this.ButtonNumber = "";
            this.ButtonLabelText = "Database Tools";
            this.bExportAuditLog = bExportAuditLog;
            bExportAuditLog.ButtonDownDelegate += new Button_164_62.FunctionButtonDownDelegate(InterpretCommand_NOTHROW);
            bInjectProducts.ButtonDownDelegate += new Button_164_62.FunctionButtonDownDelegate(InterpretCommand_NOTHROW);
            mNewEntityIsDisabled = true;
            mDeleteEntityIsDisabled = true;
            mCancelIsDisabled = true;
            mEditIsDisabled = true;
            mSaveIsDisabled = true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmd"></param>
        private void InterpretCommand_NOTHROW(int cmd)
        {
            try
            {
                switch (cmd)
                {
                    case 0:
                        SaveAuditLogToCsv();
                        break;
                    case 1:
                        InjectProductData();
                        break;
                    default:
                        break;
                }
            }
            catch (System.Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGEDATATOOLS_INTERP_COMMAND, exc);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void SaveAuditLogToCsv()
        {
            FileStream fs = null;
            StreamWriter m_streamWriter = null;

            try
            {
                Microsoft.Win32.SaveFileDialog saveFileDialog = new Microsoft.Win32.SaveFileDialog();

                saveFileDialog.Title = "Save System Log Data to a .csv File";
                saveFileDialog.FileName = "";
                saveFileDialog.Filter = ".csv Files|*.csv";
                saveFileDialog.RestoreDirectory = true;
                Nullable<bool> result = saveFileDialog.ShowDialog();

                if (true == result)
                {
                    System.Windows.MessageBox.Show("The system will now export the audit log data.  This operation could take a while depending on the size of the audit log file.", "Export Audit Log", System.Windows.MessageBoxButton.OK);

                    string filename = saveFileDialog.FileName;

                    fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
                    m_streamWriter = new StreamWriter(fs);

                    // Write to the file using StreamWriter class 
                    m_streamWriter.BaseStream.Seek(0, SeekOrigin.Begin);

                    using (DominicaEntities logContext = new DominicaEntities(DominicaEntities.GetEfConString()))
                    {
                        var query = from PCILOG in logContext.PCILOGS select PCILOG;

                        if (query.Count() > 0)
                        {
                            m_streamWriter.WriteLine("Access Db Id, User Db Id, Access Time, Access Action");
                            foreach (PCILOG s in query)
                            {
                                m_streamWriter.WriteLine("{0},{1},{2},{3}", s.Id, USER.GetUserNameStr(s.UserId, Context) + "-" + s.UserId, s.DateStamp, s.Action);
                            }
                            m_streamWriter.Flush();
                            m_streamWriter.Close();
                            fs.Close();

                            System.Windows.MessageBox.Show("All records in the audit database have been exported.", "Complete", System.Windows.MessageBoxButton.OK);
                        }
                        else
                        {
                            System.Windows.MessageBox.Show("The logging file database does not contain any records.", "Empty Database", System.Windows.MessageBoxButton.OK);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
                System.Windows.MessageBox.Show("An error was encountered and the system was unable to export the log file records.  Assure that you do not already have the file open in another program.", "Export Error", System.Windows.MessageBoxButton.OK);
            }
            finally
            {
                if (m_streamWriter != null)
                {
                    m_streamWriter.Dispose();
                }

                if (fs != null)
                {
                    fs.Dispose();
                }
            }
        }

        private void ExportSalesByProductGroup()
        {
            FileStream fs = null;
            StreamWriter m_streamWriter = null;

            try
            {
                using (DominicaEntities logContext = new DominicaEntities(DominicaEntities.GetEfConString()))
                {
                    List<Int64> ids = logContext.PRODUCT_GROUPS.Where(pg => pg.IsDeleted == false).Select(pg => pg.Id).ToList();
                    List<string> names = logContext.PRODUCT_GROUPS.Where(pg => pg.IsDeleted == false).Select(pg => pg.Name).ToList();

                    BoundObjectStringSelectionListBox mb = new BoundObjectStringSelectionListBox(names, ids);
                    mb.SetMessage("Please select the product group you would like to have a sales report on.");
                    mb.ShowDialog();

                    if (BoundObjectStringSelectionListBox.LastResponse == UserResponse.ENTER)
                    {
                        Microsoft.Win32.SaveFileDialog saveFileDialog = new Microsoft.Win32.SaveFileDialog();
                        Int64 catId = BoundObjectStringSelectionListBox.ChosenDbId;

                        saveFileDialog.Title = "Save System Log Data to a .csv File";
                        saveFileDialog.FileName = "";
                        saveFileDialog.Filter = ".csv Files|*.csv";
                        saveFileDialog.RestoreDirectory = true;
                        Nullable<bool> result = saveFileDialog.ShowDialog();

                        if (true == result)
                        {
                            System.Windows.MessageBox.Show("The system will now export the data.  This operation could take a while depending on the size of the file.", "Export Data", System.Windows.MessageBoxButton.OK);

                            string filename = saveFileDialog.FileName;

                            fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
                            m_streamWriter = new StreamWriter(fs);

                            // Write to the file using StreamWriter class 
                            m_streamWriter.BaseStream.Seek(0, SeekOrigin.Begin);

                            BUSINESS_DAY bd = BUSINESS_DAY.GetNow(logContext);
                            List<ORDER> ordersList = logContext.ORDERS.Where(o => o.BusinessDayId == bd.Id).ToList();
                            List<SALE> salesList = new List<SALE>();
                            foreach (ORDER order in ordersList)
                            {
                                foreach (SALE sale in order.SALES.Where(s => !s.WasCompedInEntire && !s.WasVoided && s.ProductsMainCatId == catId && !s.IsExceptionModifier && !s.IsForcedModifier && !s.IsSeeServer))
                                {
                                    salesList.Add(sale);
                                }
                            }
                            if (salesList.Count() > 0)
                            {
                                m_streamWriter.WriteLine("Count, Product Name");
                                foreach (IGrouping<Int64, SALE> salesGroups in salesList.GroupBy(g => g.ProductId).OrderByDescending(g => g.Count()))
                                {
                                    m_streamWriter.WriteLine("{0},{1}", salesGroups.Count(), salesGroups.First().ProductName);
                                }
                                m_streamWriter.Flush();
                                m_streamWriter.Close();
                                fs.Close();

                                System.Windows.MessageBox.Show("All records in the database have been exported.", "Complete", System.Windows.MessageBoxButton.OK);
                            }
                            else
                            {
                                System.Windows.MessageBox.Show("The logging file database does not contain any records.", "Empty Database", System.Windows.MessageBoxButton.OK);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
                System.Windows.MessageBox.Show("An error was encountered and the system was unable to export the log file records.  Assure that you do not already have the file open in another program.", "Export Error", System.Windows.MessageBoxButton.OK);
            }
            finally
            {
                if (m_streamWriter != null)
                {
                    m_streamWriter.Dispose();
                }

                if (fs != null)
                {
                    fs.Dispose();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void InjectProductData()
        {
            FileStream fs = null;
            StreamReader streamReader = null;

            try
            {
                Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();

                openFileDialog.Title = "Select the Product Text File";
                openFileDialog.FileName = "";
                openFileDialog.Filter = ".txt Files|*.txt";
                openFileDialog.RestoreDirectory = true;
                Nullable<bool> result = openFileDialog.ShowDialog();

                if (true == result)
                {
                    System.Windows.MessageBox.Show("The system will now import the products into the main database.", "Import Products", System.Windows.MessageBoxButton.OK);

                    string filename = openFileDialog.FileName;

                    fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
                    streamReader = new StreamReader(fs);

                    // Write to the file using StreamWriter class 
                    streamReader.BaseStream.Seek(0, SeekOrigin.Begin);

                    using (DominicaEntities dbContext = new DominicaEntities(DominicaEntities.GetEfConString()))
                    {
                        string lineStr = streamReader.ReadLine();
                        while (lineStr != null)
                        {
                            string[] splits = lineStr.Split(',');
                            if (splits.Count() == 6)
                            {
                                ///First get product name
                                string pName = splits[0].Trim();
                                char [] chars = pName.ToCharArray();

                                for (int i = 0; i < chars.Count(); i++)
                                {
                                    if (Char.IsLetter(chars[i]))
                                    {
                                        if (i != 0 && chars[i - 1] != ' ' && chars[i - 1] != '&')
                                        {
                                            chars[i] = char.ToLower(chars[i]);
                                        }
                                        else
                                        {
                                            chars[i] = char.ToUpper(chars[i]);
                                        }
                                    }
                                }

                                pName = new string(chars);
                                
                                ///Next product price
                                string priceString = splits[1].Trim().Substring(1);
                                decimal price = Convert.ToDecimal(priceString);

                                ///Next printer group
                                long printerGroupId = Convert.ToInt64(splits[2].Trim());

                                ///Next inclusive tax
                                long inclusiveTaxId = Convert.ToInt64(splits[3].Trim());

                                ///Exclusive Tax
                                long exclusiveTaxId = Convert.ToInt64(splits[4].Trim());

                                ///Revenue Type
                                long revenueTypeId = Convert.ToInt64(splits[5].Trim());

                                PRODUCT p = new PRODUCT();
                                p.Name = pName;
                                p.Price = price;
                                p.ProductGroupPrinterId = printerGroupId;
                                p.InclusiveTaxRateId = inclusiveTaxId;
                                p.ExclusiveTaxRateId = exclusiveTaxId;
                                p.RevenueTypeId = revenueTypeId;

                                dbContext.PRODUCTS.AddObject(p);
                                dbContext.SaveChanges();
                            }
                            lineStr = streamReader.ReadLine();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
                System.Windows.MessageBox.Show("An error occured while importing the product data.", "Import Error", System.Windows.MessageBoxButton.OK);
            }
            finally
            {
                if (streamReader != null)
                {
                    streamReader.Dispose();
                }

                if (fs != null)
                {
                    fs.Dispose();
                }
            }
        }
    }
}
